package eft.android.model;

import java.io.IOException;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import eft.android.controller.Weight;
import eft.android.controller.Workout;

/**
 *  
 * @author Geoffrey Bugaisky
 * 
 * Contains all the data manipulation methods
 *
 */

public class CrossfitDataManage {
	private DatabaseHelper dbHelper;
	private SQLiteDatabase database;
	
	//used in get all cols method
	private String[] allSavedColumns = {DatabaseHelper.SW_ID, DatabaseHelper.SW_TITLE,
			DatabaseHelper.SW_TYPE, DatabaseHelper.SW_DESCRIPTION, DatabaseHelper.SW_DATE,
			DatabaseHelper.SW_REPS, DatabaseHelper.SW_TIME, DatabaseHelper.SW_WEIGHT,
			DatabaseHelper.SW_NOTES};
	
	private String[] allCrossfitColumns = {DatabaseHelper.CF_ID, DatabaseHelper.CF_TITLE,
			DatabaseHelper.CF_TYPE, DatabaseHelper.CF_DESCRIPTION, DatabaseHelper.CF_REPS,
			DatabaseHelper.CF_TIME, DatabaseHelper.CF_WEIGHT};
	
	private String[] allDailyWeightColumns = {DatabaseHelper.DW_ID, DatabaseHelper.DW_WEIGHT,
			DatabaseHelper.DW_DATE};
	
	// Used to get the date in a yyyymmdd format
	Calendar c = Calendar.getInstance();
	private String tempDate = "" + c.get(Calendar.YEAR) +
			c.get(Calendar.MONTH) + c.get(Calendar.DAY_OF_MONTH);
	long currentDate = Long.parseLong(tempDate.trim());

	public CrossfitDataManage (Context context)
	{
		dbHelper = new DatabaseHelper(context);
	}
	
	public void open() throws SQLException
	{
//		DatabaseHelper dbHelper = new DatabaseHelper();
//		dbHelper = DatabaseHelper(this);
		try
		{
			dbHelper.createDatabase();
		}
		catch (IOException ioe)
		{
			throw new Error ("Error Creating Databse");
		}
		try
		{
			dbHelper.openDatabase();
		}
		catch (SQLException sqle)
		{
			throw sqle;
		}
	}
	
	public void close()
	{
		dbHelper.close();
	}
	
	/**
	 * Add a new workout to the database, only can do to savedworkout table
	 * @param title
	 * @param type
	 * @param description
	 * @param reps
	 * @param time
	 * @param weight
	 * @param notes
	 */
	
	public void addNewExcercise(String title, int type, String description, 
			String reps, long time, String weight, String notes)
	{
		//open();
		database = dbHelper.getWritableDatabase();
		ContentValues values = new ContentValues();
		values.put (DatabaseHelper.SW_TITLE, title);
		values.put (DatabaseHelper.SW_TYPE, type);
		values.put (DatabaseHelper.SW_DESCRIPTION, description);
		values.put (DatabaseHelper.SW_DATE, currentDate);
		values.put (DatabaseHelper.SW_REPS, reps);
		values.put (DatabaseHelper.SW_TIME, time);
		values.put (DatabaseHelper.SW_WEIGHT, weight);
		values.put (DatabaseHelper.SW_NOTES, notes);
		database.insert(DatabaseHelper.SAVED_WORKOUTS, null, values);
		database.close();
		//close();
	}
	
	
	/**
	 * Add a new workout to the database, only can do to savedworkout table
	 * @param title
	 * @param type
	 * @param description
	 * @param date
	 * @param reps
	 * @param time
	 * @param weight
	 * @param notes
	 */
	public void addNewExcercise(String title, int type, String description, 
			long date, String reps, long time, String weight, String notes)
	{
		//this.open();
		database = dbHelper.getWritableDatabase();
		ContentValues values = new ContentValues();
		values.put (DatabaseHelper.SW_TITLE, title);
		values.put (DatabaseHelper.SW_TYPE, type);
		values.put (DatabaseHelper.SW_DESCRIPTION, description);
		values.put (DatabaseHelper.SW_DATE, date);
		values.put (DatabaseHelper.SW_REPS, reps);
		values.put (DatabaseHelper.SW_TIME, time);
		values.put (DatabaseHelper.SW_WEIGHT, weight);
		values.put (DatabaseHelper.SW_NOTES, notes);
		database.insert(DatabaseHelper.SAVED_WORKOUTS, null, values);
		database.close();
		//this.close();
	}
	
	
	/**
	 * Gets all workouts in a table of the database
	 * @param cfworkouts a flag, true if one wants workouts from Crossfit Workout table,
	 *        false otherwise
	 * @return List<Workout> a list of all workouts in the table
	 */
	
	public List<Workout> getAllSavedWorkouts(boolean cfworkouts)
	{
		List<Workout> workouts = new ArrayList<Workout>();
		database = dbHelper.getReadableDatabase();
		Cursor cursor;
		
		if (cfworkouts)
		{
			cursor = database.query(DatabaseHelper.CROSSFIT_WORKOUTS, allCrossfitColumns,
					null, null, null, null, null);
			if(cursor.moveToFirst())
			{
				while (!cursor.isAfterLast())
				{
					Workout workout = cursorToCrossfitWorkout(cursor);
					workouts.add(workout);
					cursor.moveToNext();
				}
			//cursor.close();
			//return workouts;
			}
			else return null;
		}
		
		
		else
		{
			cursor = database.query(DatabaseHelper.SAVED_WORKOUTS, allSavedColumns,
					null, null, null, null, null);
		
			if(cursor.moveToFirst())
			{
		
				while (!cursor.isAfterLast())
				{
					Workout workout = cursorToSavedWorkout(cursor);
					workouts.add(workout);
					cursor.moveToNext();
				}
				//cursor.close();
				//return workouts;
			}
			else return null;
		}
		
		cursor.close();
		database.close();
		return workouts;
	}
	/**
	 * Get a workout by id
	 * @param cfworkouts
	 * @param id the id of the workout searching for
	 * @return A Workout object
	 */
	public Workout getWorkoutById(boolean cfworkouts, int id)
	{
		Workout workout = new Workout();
				
		Cursor cursor;
		database = dbHelper.getWritableDatabase();
		if (cfworkouts)
		{
			cursor = database.query(DatabaseHelper.CROSSFIT_WORKOUTS, allCrossfitColumns,
					DatabaseHelper.CF_ID + "=" + id, null, null, null, null);
			cursor.moveToNext();
			workout = cursorToCrossfitWorkout(cursor);
		}
		
		else
		{
			cursor = database.query(DatabaseHelper.SAVED_WORKOUTS, allSavedColumns,
					DatabaseHelper.SW_ID + "=" + id, null, null, null, null);
			cursor.moveToNext();
			workout = cursorToSavedWorkout(cursor);
		}
		
		cursor.close();
		database.close();
		return workout;
	}
	/**
	 * Get all workouts in saved workouts done on a specific date
	 * @param date the date wanted to be searched for, in the format YYYYMMDD
	 * @return a list of Workout objects performed on a requested date 
	 */
	public List<Workout> getSavedWorkoutsByDate(long date)
	{
		List<Workout> workouts = new ArrayList<Workout>();
		database = dbHelper.getReadableDatabase();
		Cursor cursor = database.query(DatabaseHelper.SAVED_WORKOUTS, allSavedColumns,
				DatabaseHelper.SW_DATE + "=" + date, null, null, null, null);
		
		for ( int i = cursor.getCount(); i < 0; i--)
		{
			Workout workout = cursorToSavedWorkout(cursor);
			workouts.add(workout);
			cursor.moveToNext();
		}
		
		cursor.close();
		database.close();
		return workouts;
	}
	
	public void updateWorkout(Workout workout)
	{
		database = dbHelper.getWritableDatabase();
		ContentValues values = new ContentValues();
		values.put (DatabaseHelper.SW_ID, workout.getID());
		values.put (DatabaseHelper.SW_TITLE, workout.getTitle());
		values.put (DatabaseHelper.SW_TYPE, workout.getType());
		values.put (DatabaseHelper.SW_DESCRIPTION, workout.getDescription());
		values.put (DatabaseHelper.SW_DATE, workout.getDate());
		values.put (DatabaseHelper.SW_REPS, workout.getReps());
		values.put (DatabaseHelper.SW_TIME, workout.getTime());
		values.put (DatabaseHelper.SW_WEIGHT, workout.getWeight());
		values.put (DatabaseHelper.SW_NOTES, workout.getNotes());
		database.update (DatabaseHelper.SAVED_WORKOUTS, values, DatabaseHelper.SW_ID + "=" + workout.getID(), null);
		database.close();
	}
	
	
	//the delete options, first one Does not work
/*	public void deleteEntryByID(int id)
 *	{
 *		database.delete(DatabaseHelper.SAVED_WORKOUTS, DatabaseHelper.SW_ID + "=" + id, null);
 *	}
 */
	
	public void deleteWorkout(Workout workout)
	{
		database = dbHelper.getWritableDatabase();
		long id = workout.getID();
		database.delete(DatabaseHelper.SAVED_WORKOUTS, DatabaseHelper.SW_ID + "=" + id , null);
		database.close();
	}
	
	/**
	 * Used to convert a cursor to a workout, only used on the savedworkout table
	 * @param cursor
	 * @return
	 */
	/* get a specific workout from the database */
	private Workout cursorToSavedWorkout(Cursor cursor) 
	{
		Workout workout = new Workout();
		workout.setID(cursor.getLong(0));
		workout.setTitle(cursor.getString(1));
		workout.setType(cursor.getInt(2));
		workout.setDescription(cursor.getString(3));
		workout.setDate(cursor.getLong(4));
		workout.setReps(cursor.getString(5));
		workout.setTime(cursor.getLong(6));
		workout.setWeight(cursor.getString(7));
		workout.setNotes(cursor.getString(8));
		return workout;
	}
	
	/**
	 * Used to convert a cursor to a workout, only used on the crossfitworkout table
	 * @param cursor
	 * @return
	 */
	private Workout cursorToCrossfitWorkout(Cursor cursor) 
	{
		Workout workout = new Workout();
		workout.setID(cursor.getLong(0));
		workout.setTitle(cursor.getString(1));
		workout.setType(cursor.getInt(2));
		workout.setDescription(cursor.getString(3));
		workout.setReps(cursor.getString(4));
		workout.setTime(cursor.getLong(5));
		workout.setWeight(cursor.getString(6));
		return workout;
	}
	
	
	//------------------------Weight table interactions---------------//
	
	
	/**
	 * Add Daily Weight to the database
	 * @param weight
	 */
	/*
	public void addDailyWeight(int weight)
	{
		//Find if the value already exists
		if (!exists(currentDate))
		{
			database = dbHelper.getWritableDatabase();
			ContentValues values = new ContentValues();
			values.put (DatabaseHelper.DW_ID, currentDate);
			values.put (DatabaseHelper.DW_WEIGHT, weight);
			values.put (DatabaseHelper.DW_DATE, currentDate);
			database.insert (DatabaseHelper.DAILY_WEIGHT, null, values);
			database.close();
		}
		else
			updateDailyWeight(weight);
	}
	*/

	/**
	 * Add Daily Weight to the database
	 * @param weight
	 * @param date
	 */
	public void addDailyWeight(double weight, long date)
	{
		//this.open();
		database = dbHelper.getWritableDatabase();
		//Find if the value already exists
		if (!exists(date))
		{
			
			ContentValues values = new ContentValues();
			values.put (DatabaseHelper.DW_ID, date);
			values.put (DatabaseHelper.DW_WEIGHT, weight);
			values.put (DatabaseHelper.DW_DATE, date);
			database.insert (DatabaseHelper.DAILY_WEIGHT, null, values);

		}
		
		else
			updateDailyWeight(weight, date);
		
		database.close();		
		//close();
	}
	
	
	public Weight getWeightEntry(long date)
	{
		Weight weight = new Weight();
		database = dbHelper.getReadableDatabase();
		if (exists(date))
		{
			Cursor cursor = database.query(DatabaseHelper.DAILY_WEIGHT, allDailyWeightColumns,
					DatabaseHelper.DW_ID + "=" + date, null, null, null, null);
			cursor.moveToFirst();
			weight = cursorToWeight(cursor);
			cursor.close();
			database.close();
			return weight;
		}
		
		else
		{
			database.close();
			return null;
		}

	}
	
	public void deleteWeight(long date)
	{
		if(exists(date))
		{
			database = dbHelper.getWritableDatabase();
			database.delete(DatabaseHelper.DAILY_WEIGHT, DatabaseHelper.DW_ID + "=" + date, null);
			database.close();
		}
	}
	
	//used to check if an id exists, true, else false
	private boolean exists(long _id)
	{	
		Cursor cursor;
		try{
			cursor = database.query(DatabaseHelper.DAILY_WEIGHT, allDailyWeightColumns,
				DatabaseHelper.DW_ID + "=" + _id, null, null, null, null);
		}
		catch (Exception ex){
			return false;
		}
		boolean exists = (cursor.getCount() > 0);
		cursor.close();
		return exists;
	}
	
	//used to update weight rather than create a new entry
	/*
	private void updateDailyWeight(double weight)
	{
		database = dbHelper.getWritableDatabase();
		ContentValues values = new ContentValues();
		values.put (DatabaseHelper.DW_ID, currentDate);
		values.put (DatabaseHelper.DW_WEIGHT, weight);
		values.put (DatabaseHelper.DW_DATE, currentDate);
		database.update (DatabaseHelper.DAILY_WEIGHT, values, DatabaseHelper.DW_ID + "=" + currentDate,
				null);
		database.close();
	}
    */
	
	private void updateDailyWeight(double weight, long date)
	{
//		database = dbHelper.getWritableDatabase();
		ContentValues values = new ContentValues();
		values.put (DatabaseHelper.DW_ID, date);
		values.put (DatabaseHelper.DW_WEIGHT, weight);
		values.put (DatabaseHelper.DW_DATE, date);
		database.update (DatabaseHelper.DAILY_WEIGHT, values, DatabaseHelper.DW_ID + "=" + date,
				null);
//		database.close();
	}
	

	private Weight cursorToWeight(Cursor cursor) 
	{
		Weight weight = new Weight();
		weight.setID(cursor.getLong(0));
		weight.setWeight(cursor.getDouble(1));
		weight.setDate(cursor.getLong(2));
		return weight;
	}
}
